package com.crm.business.agreement.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ancun.netsign.model.OpenTemplateOutput;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crm.business.admin.service.IAdminFileService;
import com.crm.business.agreement.mapper.BillAgreementTemplateMapper;
import com.crm.business.agreement.service.IBillAgreementSealSubjectService;
import com.crm.business.agreement.service.IBillAgreementTemplateParamsService;
import com.crm.business.agreement.service.IBillAgreementTemplateService;
import com.crm.business.agreement.service.IBillAgreementTemplateSignerService;
import com.crm.business.servlet.BaseServiceImpl;
import com.crm.business.utils.UserUtil;
import com.crm.common.admin.entity.PO.AdminFile;
import com.crm.common.agreement.common.AgreementCodeEnum;
import com.crm.common.agreement.common.AiQianUtils;
import com.crm.common.agreement.entity.BO.TemplateBo;
import com.crm.common.agreement.entity.BO.TemplateParamsBO;
import com.crm.common.agreement.entity.BO.TemplateSignerBO;
import com.crm.common.agreement.entity.PO.BillAgreementSealSubject;
import com.crm.common.agreement.entity.PO.BillAgreementTemplate;
import com.crm.common.agreement.entity.PO.BillAgreementTemplateParams;
import com.crm.common.agreement.entity.PO.BillAgreementTemplateSigner;
import com.crm.common.enums.ErrorCodeConstants;
import com.crm.common.exception.CustomException;
import com.crm.common.ka.core.servlet.upload.FileServiceFactory;
import com.crm.common.ka.core.servlet.upload.UploadEntity;
import com.crm.common.utils.DateUtils;
import com.crm.common.utils.StringUtils;
import com.crm.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class BillAgreementTemplateServiceImlp extends BaseServiceImpl<BillAgreementTemplateMapper, BillAgreementTemplate> implements IBillAgreementTemplateService {

    @Autowired
    private AiQianUtils aiQianUtils;

    @Autowired
    private IBillAgreementTemplateSignerService billAgreementTemplateSignerService;

    @Autowired
    private IBillAgreementTemplateParamsService billAgreementTemplateParamsService;

    @Autowired
    private IAdminFileService adminFileService;

    @Autowired
    private IBillAgreementSealSubjectService billAgreementSealSubjectService;


    public String save(Long fileId,TemplateBo model) throws IOException {

        //上传模板文件

        AdminFile adminFile = adminFileService.getById(fileId);
        if(!Optional.ofNullable(adminFile).isPresent()){
            throw new CustomException(AgreementCodeEnum.SAVE_TEMPLATE_FILE_IS_UNDIFIND.getMsg(),AgreementCodeEnum.SAVE_TEMPLATE_FILE_IS_UNDIFIND.getCode());
        }

        List<TemplateSignerBO> signers = model.getSignerList();
        if(CollectionUtils.isEmpty(signers)){
            throw new CustomException(AgreementCodeEnum.TEMPLATE_SIGNER_NEED_ON_PARTY.getMsg(),AgreementCodeEnum.TEMPLATE_SIGNER_NEED_ON_PARTY.getCode());
        }
        for(TemplateSignerBO bo : signers ){
            if(StringUtils.isEmpty(bo.getSignerKey())){
                throw new CustomException(AgreementCodeEnum.TEMPLATE_SIGNER_NEED_ON_PARTY.getMsg(),AgreementCodeEnum.TEMPLATE_SIGNER_NEED_ON_PARTY.getCode());
            }
            BillAgreementSealSubject signer = billAgreementSealSubjectService.getBaseMapper().selectById(bo.getSubjectId());
            if(!Optional.ofNullable(signer).isPresent()){
                throw new CustomException(AgreementCodeEnum.TEMPLATE_SIGNER_IS_ERROR.getMsg(),AgreementCodeEnum.TEMPLATE_SIGNER_IS_ERROR.getCode());
            }
        }


        UploadEntity entity = new UploadEntity(adminFile.getFileId() + "", adminFile.getName(), adminFile.getSize(), adminFile.getBatchId(), "0");
        entity.setPath(adminFile.getPath());
        InputStream inputStream = FileServiceFactory.build().downFile(entity);

        String templateNo = aiQianUtils.uploadTemplate(inputStream,adminFile.getName(),1);

        String respBody =  aiQianUtils.openTemplate(templateNo,model.getParamsList());

        Date now = DateUtils.getNowDate();

        List<BillAgreementTemplateSigner> signerList = new ArrayList<BillAgreementTemplateSigner>();

        for(TemplateSignerBO bo : model.getSignerList()){
            BillAgreementTemplateSigner signer = new BillAgreementTemplateSigner();
            BeanUtil.copyProperties(bo,signer);
            signer.setCreateTime(now);
            signerList.add(signer);
        }

        List<BillAgreementTemplateParams> paramsList = new ArrayList<BillAgreementTemplateParams>();

        for(TemplateParamsBO bo : model.getParamsList()){
            BillAgreementTemplateParams params = new BillAgreementTemplateParams();
            BeanUtil.copyProperties(bo,params);
            params.setCreateTime(now);
            paramsList.add(params);
        }

        List<String> enterpriseNameList = signerList.stream().map(BillAgreementTemplateSigner::getEnterpriseName).collect(Collectors.toList());
        String enterpriseNames =  String.join(",", enterpriseNameList);

        BillAgreementTemplate template = new BillAgreementTemplate();
        BeanUtil.copyProperties(model,template);
        template.setEnterpriseNames(enterpriseNames);
        template.setCreateUserId(UserUtil.getUser().getUserId());
        template.setCreateUserName(UserUtil.getUser().getRealname());
        template.setCreateTime(now);
        template.setTemplateNo(templateNo);
        template.setTemplateOssUrl(String.valueOf(fileId));

        int i = SpringUtils.getBean(IBillAgreementTemplateService.class).saveDate(template,signerList,paramsList);
        if(i > 0){
            return respBody;
        }else{
            throw new CustomException(AgreementCodeEnum.SAVE_TEMPLATE_FAIL.getMsg(),AgreementCodeEnum.SAVE_TEMPLATE_FAIL.getCode());
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveDate(BillAgreementTemplate template,List<BillAgreementTemplateSigner> signerList,List<BillAgreementTemplateParams> paramsList){
        int i = 0;
        if(Optional.ofNullable(template.getTemplateId()).isPresent()){
            i = getBaseMapper().updateById(template);
            billAgreementTemplateSignerService.deleteByTemplateId(template.getTemplateId());
            billAgreementTemplateParamsService.deleteByTemplateId(template.getTemplateId());
        }else{
            template.setStatus(0);
            i = getBaseMapper().insert(template);
        }

        for(BillAgreementTemplateSigner signer : signerList){
            signer.setTemplateId(template.getTemplateId());
        }

        for(BillAgreementTemplateParams params : paramsList){
            params.setTemplateId(template.getTemplateId());
        }
        billAgreementTemplateSignerService.addList(signerList);
        billAgreementTemplateParamsService.addList(paramsList);
        return i;
    }

    @Override
    public String openTemplateCallBack(String templateIdent){
        QueryWrapper<BillAgreementTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("template_no",templateIdent);
        BillAgreementTemplate template = getBaseMapper().selectOne(queryWrapper);
        if(Optional.ofNullable(template).isPresent()){
            aiQianUtils.syncTemplate(templateIdent);
            OpenTemplateOutput output = aiQianUtils.templateInfo(template.getTemplateNo());

            if(Optional.ofNullable(output).isPresent()) {
                String url = output.getSyncUrl();
                return url;
            }
        }
        return StringUtils.EMPTY;
    }

    @Override
    public IPage<BillAgreementTemplate> queryPageList(TemplateBo model){

        IPage<BillAgreementTemplate> page = new Page<>(model.getPage(), model.getLimit());
        QueryWrapper<BillAgreementTemplate> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(model.getTemplateName())){
            queryWrapper.like("template_name",model.getTemplateName());
        }
        if(StringUtils.isNotEmpty(model.getTemplateNo())){
            queryWrapper.eq("template_no",model.getTemplateNo());
        }
        if(ObjectUtils.isNotEmpty(model.getStatus())){
            queryWrapper.eq("status",model.getStatus());
        }
        queryWrapper.orderByDesc( "template_id");
        IPage<BillAgreementTemplate> pageInfo = baseMapper.selectPage(page, queryWrapper);
        return pageInfo;
    }

    @Override
    public List<BillAgreementTemplate> queryList(TemplateBo model){

        QueryWrapper<BillAgreementTemplate> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(model.getTemplateName())){
            queryWrapper.like("template_name",model.getTemplateName());
        }
        if(StringUtils.isNotEmpty(model.getTemplateNo())){
            queryWrapper.eq("template_no",model.getTemplateNo());
        }
        if(ObjectUtils.isNotEmpty(model.getStatus())){
            queryWrapper.eq("status",model.getStatus());
        }
        queryWrapper.orderByDesc( "template_id");
        List<BillAgreementTemplate> list = baseMapper.selectList(queryWrapper);
        return list;
    }



    public String update(Long fileId, TemplateBo model) throws IOException{


        if(!Optional.ofNullable(model.getTemplateId()).isPresent()){
            throw new CustomException(ErrorCodeConstants.CONFIG_MISSING.getMsg(),ErrorCodeConstants.CONFIG_MISSING.getCode());
        }
        BillAgreementTemplate template = getBaseMapper().selectById(model.getTemplateId());

        if(!Optional.ofNullable(template).isPresent()){
            throw new CustomException(ErrorCodeConstants.CONFIG_ERROR.getMsg(),ErrorCodeConstants.CONFIG_ERROR.getCode());
        }

        //上传模板文件
        AdminFile adminFile = adminFileService.getById(fileId);
        if(!Optional.ofNullable(adminFile).isPresent()){
            throw new CustomException(AgreementCodeEnum.SAVE_TEMPLATE_FILE_IS_UNDIFIND.getMsg(),AgreementCodeEnum.SAVE_TEMPLATE_FILE_IS_UNDIFIND.getCode());
        }

        String oldTemplateNo = template.getTemplateNo();

        UploadEntity entity = new UploadEntity(adminFile.getFileId() + "", adminFile.getName(), adminFile.getSize(), adminFile.getBatchId(), "0");
        entity.setPath(adminFile.getPath());
        InputStream inputStream = FileServiceFactory.build().downFile(entity);
        String templateNo = aiQianUtils.uploadTemplate(inputStream,adminFile.getName(),1);

        String respBody =  aiQianUtils.openTemplate(templateNo,model.getParamsList());
        Date now = DateUtils.getNowDate();

        List<BillAgreementTemplateSigner> signerList = new ArrayList<BillAgreementTemplateSigner>();

        for(TemplateSignerBO bo : model.getSignerList()){
            BillAgreementTemplateSigner signer = new BillAgreementTemplateSigner();
            signer.setSubjectId(bo.getSubjectId());
            signer.setEnterpriseName(bo.getEnterpriseName());
            signer.setSignerKey(bo.getSignerKey());
            signer.setCreateTime(now);
            signerList.add(signer);
        }

        List<BillAgreementTemplateParams> paramsList = new ArrayList<BillAgreementTemplateParams>();

        for(TemplateParamsBO bo : model.getParamsList()){
            BillAgreementTemplateParams params = new BillAgreementTemplateParams();
            params.setParamsKey(bo.getParamsKey());
            params.setParamsType(bo.getParamsType());
            params.setCreateTime(now);
            paramsList.add(params);
        }

        List<String> enterpriseNameList = signerList.stream().map(BillAgreementTemplateSigner::getEnterpriseName).collect(Collectors.toList());
        String enterpriseNames =  String.join(",", enterpriseNameList);

        BillAgreementTemplate upTemplate = new BillAgreementTemplate();
        upTemplate.setTemplateName(model.getTemplateName());
        upTemplate.setTemplateId(template.getTemplateId());
        upTemplate.setTemplateOssUrl(String.valueOf(fileId));
        upTemplate.setEnterpriseNames(enterpriseNames);
        upTemplate.setTemplateNo(templateNo);
        upTemplate.setTemplateOssUrl(String.valueOf(fileId));
        upTemplate.setUpdateTime(now);

        int i = SpringUtils.getBean(IBillAgreementTemplateService.class).saveDate(upTemplate,signerList,paramsList);
        if(i > 0){
            aiQianUtils.cancelSyncTemplate(oldTemplateNo);
            aiQianUtils.delTemplate(oldTemplateNo);
            return respBody;
        }else{
            throw new CustomException(AgreementCodeEnum.SAVE_TEMPLATE_FAIL.getMsg(),AgreementCodeEnum.SAVE_TEMPLATE_FAIL.getCode());
        }
    }


    @Override
    public Map<String,Object> getTemplateInfo(Long templateId){

        Map<String,Object> result = new HashMap<>();

        BillAgreementTemplate template = getBaseMapper().selectById(templateId);

        if(!Optional.ofNullable(template).isPresent()){
            throw new CustomException(ErrorCodeConstants.CONFIG_ERROR.getMsg(),ErrorCodeConstants.CONFIG_ERROR.getCode());
        }

        QueryWrapper<BillAgreementTemplateSigner> querySignerWrapper = new QueryWrapper<>();
        querySignerWrapper.eq("template_id",templateId);
        List<BillAgreementTemplateSigner> templateSignerList = billAgreementTemplateSignerService.getBaseMapper().selectList(querySignerWrapper);

        QueryWrapper<BillAgreementTemplateParams> queryParamsWrapper = new QueryWrapper<>();
        queryParamsWrapper.eq("template_id",templateId);
        List<BillAgreementTemplateParams> templateParamsList = billAgreementTemplateParamsService.getBaseMapper().selectList(queryParamsWrapper);


        TemplateBo bo = new TemplateBo();
        BeanUtil.copyProperties(template,bo);

        List<TemplateSignerBO> signerList = new ArrayList<>();
        for(BillAgreementTemplateSigner signer : templateSignerList){
            TemplateSignerBO signerBO = new TemplateSignerBO();
            BeanUtil.copyProperties(signer,signerBO);
            signerList.add(signerBO);
        }

        List<TemplateParamsBO> paramsList = new ArrayList<>();
        for(BillAgreementTemplateParams params : templateParamsList){
            TemplateParamsBO paramsBO = new TemplateParamsBO();
            BeanUtil.copyProperties(params,paramsBO);
            paramsList.add(paramsBO);
        }

        bo.setSignerList(signerList);
        bo.setParamsList(paramsList);


        result.put("model",bo);

        AdminFile adminFile = adminFileService.getById(Long.valueOf(bo.getTemplateOssUrl()));
        result.put("fileId",String.valueOf(adminFile.getFileId()));
        result.put("fileName",adminFile.getName());
        return result;
    }


    @Override
    public Map<String,Object> previewUrl(Long templateId){

        Map<String,Object> result = new HashMap<>();

        BillAgreementTemplate template = getBaseMapper().selectById(templateId);

        if(!Optional.ofNullable(template).isPresent()){
            throw new CustomException(ErrorCodeConstants.CONFIG_ERROR.getMsg(),ErrorCodeConstants.CONFIG_ERROR.getCode());
        }

        OpenTemplateOutput output = aiQianUtils.templateInfo(template.getTemplateNo());

        if(Optional.ofNullable(output).isPresent()){
            String url = output.getSyncUrl();
            result.put("result",url);
            return result;
        }else{
            throw new CustomException(AgreementCodeEnum.TEMPLATE_PREVIEW_URL_NOT_EXISTENCE.getMsg(),AgreementCodeEnum.TEMPLATE_PREVIEW_URL_NOT_EXISTENCE.getCode());
        }

    }


    public int upStatus(Long templateId,Integer status){
        BillAgreementTemplate template = getBaseMapper().selectById(templateId);

        if(!Optional.ofNullable(template).isPresent()){
            throw new CustomException(ErrorCodeConstants.CONFIG_ERROR.getMsg(),ErrorCodeConstants.CONFIG_ERROR.getCode());
        }
        BillAgreementTemplate upTemplate = new BillAgreementTemplate();
        upTemplate.setTemplateId(templateId);
        upTemplate.setStatus(status);
        upTemplate.setUpdateTime(DateUtils.getNowDate());

        int i = getBaseMapper().updateById(upTemplate);
        return i;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delTemplate(Long templateId){
        BillAgreementTemplate template = getBaseMapper().selectById(templateId);

        if(!Optional.ofNullable(template).isPresent()){
            throw new CustomException(ErrorCodeConstants.CONFIG_ERROR.getMsg(),ErrorCodeConstants.CONFIG_ERROR.getCode());
        }

        if(Integer.valueOf(1).equals(template.getStatus())){
            throw new CustomException(AgreementCodeEnum.TEMPLATE_IS_USING_CAN_NOT_DEL.getMsg(),AgreementCodeEnum.TEMPLATE_IS_USING_CAN_NOT_DEL.getCode());
        }

        int i = getBaseMapper().deleteById(templateId);
        billAgreementTemplateSignerService.deleteByTemplateId(template.getTemplateId());
        billAgreementTemplateParamsService.deleteByTemplateId(template.getTemplateId());
        aiQianUtils.cancelSyncTemplate(template.getTemplateNo());
        aiQianUtils.delTemplate(template.getTemplateNo());
        return i;
    }

}
